package com.zyf.pattern.delegate.mvc;

import com.zyf.pattern.delegate.mvc.controller.MemberAction;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 委派模式例子一：模拟springMVC中的ServletDispatcher
 * 相当于项目经理的角色
 * create by yifeng
 */
public class ServletDispatcher {

    private List<Handler> handlerMapping = new ArrayList<>();

    public ServletDispatcher() {
        Handler handler = new Handler();
        handler.setController(new MemberAction());
        handler.setUrl("/web/getMemberById.json");
        try {
            handler.setMethod(MemberAction.class
                    .getMethod("getMemberById", new Class[]{String.class}));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        handlerMapping.add(handler);
    }

    public void doService(HttpServletRequest request, HttpServletResponse response) {
        doDispatch(request, response);
    }

    // 委派模式
    private void doDispatch(HttpServletRequest request, HttpServletResponse response) {
        // <sevlet> </servlet>
        // <servlet-pattern></servlet-pattern>
        // 1. 获取用户请求的url,
        // 如果按照J2EE的标准，每个url对应一个Servlet，url由浏览器输入
        String requestURI = request.getRequestURI();
        // 2. servlet拿到url以后，要做权衡（要做判断，要做选择）
        // 根据用户请求的URL，去找到这个url对应的某一个java类方法


        // 3. 通过拿到的url去handlerMapping（把它认为是策略）
        Handler handler = null;
        for (Handler h : handlerMapping) {
            if (requestURI.equals(h.getUrl())) {
                handler = h;
                break;
            }
        }

        // 4. 将具体的任务分发给Method（通过反射区调用其对应的方法)
        Object object = null;
        try {
            object = handler.getMethod().invoke(handler.getController(),
                    request.getParameter("mid"));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        // 5. 获取到Method执行的结果，通过Response返回出去
//        response.getWriter().write();

    }


    class Handler {
        private Object controller;
        private Method method;
        private String url;

        public Object getController() {
            return controller;
        }

        public void setController(Object controller) {
            this.controller = controller;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }
    }

}
